package com.tte.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @PackageName: com.tte.common.config
 * @ClaseName: AsyncScheduledTaskConfig
 * @Description: 在方法上添加@Async注解，然后还需要在@SpringBootApplication启动类或者@Configuration注解类上
 * 添加注解@EnableAsync启动多线程注解，@Async就会对标注的方法开启异步多线程调用，注意，这个方法的类一定要交给Spring容器来管理
 * @Author: DongWH
 * @Date: 2022/11/2 21:57
 * @params *@params $
 */
@Configuration
@EnableAsync
public class ThreadPoolTaskExecutorConfig {

    private static int corePoolSize;
    private static int maximumPoolSize;
    private static int queueCapacity;
    private static int keepAliveSeconds;

    @Bean("taskPool")
    public static ThreadPoolTaskExecutor taskPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程数
        executor.setCorePoolSize(corePoolSize);
        //最大线程数
        executor.setMaxPoolSize(maximumPoolSize);
        //任务队列的大小
        executor.setQueueCapacity(queueCapacity);
        //设置线程空闲时间（秒）
        executor.setKeepAliveSeconds(keepAliveSeconds);
        //线程前缀名
        executor.setThreadNamePrefix("Task_Async_");

        /**
         * 拒绝处理策略
         * CallerRunsPolicy()：交由调用方线程运行，比如 main 线程。
         * AbortPolicy()：直接抛出异常。
         * DiscardPolicy()：直接丢弃。
         * DiscardOldestPolicy()：丢弃队列中最老的任务。
         */
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //线程初始化
        executor.initialize();
        return executor;
    }

    @Value("${pool.corePoolSize}")
    public void setCorePoolSize(int corePoolSize) {
        ThreadPoolTaskExecutorConfig.corePoolSize = corePoolSize;
    }

    @Value("${pool.maximumPoolSize}")
    public void setMaximumPoolSize(int maximumPoolSize) {
        ThreadPoolTaskExecutorConfig.maximumPoolSize = maximumPoolSize;
    }

    @Value("${pool.queueCapacity}")
    public void setQueueCapacity(int queueCapacity) {
        ThreadPoolTaskExecutorConfig.queueCapacity = queueCapacity;
    }

    @Value("${pool.keepAliveSeconds}")
    public void setKeepAliveSeconds(int keepAliveSeconds) {
        ThreadPoolTaskExecutorConfig.keepAliveSeconds = keepAliveSeconds;
    }

}
